10. Light and Versatile Graphics Library (LVGL)
The LVGL is an open-source lightweight embedded graphics library, for displays and various input devices, providing easy-to-use graphical elements, attractive visual effects and a low memory footprint. It requires one FB in MCU, external RAM or display controller, a graphics buffer for the LVGL larger than the horizontal resolution of the display controller in pixels and 8kB RAM. More than 30 powerful widgets are supported, such as buttons, arcs, bars, sliders, switches, text areas, images, etc. The display, in which the content will be rendered, can be any resolution from small monochrome displays to Full HD monitors, with custom color formats. The LVGL gives the advantage to the user to achieve great performance and high quality by flexible buffering modes and low memory usage. It has a configurable refresh period, giving the opportunity to the user to adjust it according to the system capabilities, in order to maximize the total displayed frames per second. Advanced graphics with animations, anti-aliasing, opacity, masking, image transformations (real time zoom, real time rotation, scaling, etc.) and smooth scrolling can be rendered by the graphics library with or without GPU acceleration.The flexible and extendable draw pipeline provides hooks to accelerate, with the use of a GPU, some rendering functions or even replace the built-in software renderer (EXTERNAL_RENDERER). With regards to the texture rendering, UTF-8, anti-aliasing, font compression, subpixel rendering, multi-language support (Arabic and Persian) and bidirectional text are supported. Different type and multiple input devices, such as keyboards, touch and mouse with gesture recognition can be also handled.
The LVGL supports various color formats from 8 bits to 32 bits. The convention is that the frame buffer and the resources should have the same color depth. Transparency of the resource images can be applied either with the use of FB with a color depth with alpha channel enabled or with color keying.
The options for the supported color depth of the FB are
1 byte per pixel (monochrome),
8 bits per pixel (RGB332),
16 bits per pixel (RGB565),
32 bits per pixel (ARGB8888).
The supported color format of the resource images can be:
RGB with or without transparency,
I1, I2, I4, I8,
A1, A2, A4, A8,
raw images with or without transparency (SW support ONLY).
The LVGL sub-folder has the LVGL-related files, as shown in Figure 12, and is located under application’s ui folder.
The lv_port folder has all the files that LVGL needs to communicate with the DA1470x LCD Controller and accelerate some of the common rendering functions. All functionality is already configured and because of that the developer does not have to modify anything.
The lvgl folder has the source code of the LVGL, a README.md file introducing the user to the library and finally the terms and conditions under which the library is released.

Figure 12 LVGL Folder Structure
10.1. Configuration Parameters
The various configurations of the LVGL library are included in a configuration header file for LVGL called lv_conf.h. The user can modify this header to set the library’s basic behavior, disable unused modules and features, adjust the size of memory buffers in compile-time, etc. The most important macro that should be set at least is LV_COLOR_DEPTH according to the display’s color depth. This is the parameter for setting the color depth of the FB.
In the following table, the user can find explanation of the most common and important macros.
Macro Name |
Default Value |
Description |
---|---|---|
DLG_LVGL_CF |
1 |
Enable additional color format support |
DLG_LVGL_CF_SUB_BYTE_SWAP |
0 |
Enable sub byte color formats to be swapped. If disabled, which is recommended for performance, bitmaps need to be in correct order. |
LV_COLOR_DEPTH |
16 |
Color depth: 1 (1 byte per pixel), 8 (RGB332), 16 (RGB565), 32 (ARGB8888) |
LV_COLOR_16_SWAP |
0 |
Swap the 2 bytes of RGB565 color. Useful if the display has an 8-bit interface (e.g. SPI) |
LV_COLOR_SCREEN_TRANSP |
0 |
Enable more complex drawing routines to manage screens transparency. Can be used if the UI is above another layer. Requires LV_COLOR_DEPTH = 32 colors and the screen’s bg_opa should be set to non LV_OPA_COVER value. |
LV_COLOR_CHROMA_KEY |
lv_color_hex(0x00FF00) |
Images pixels with this color will not be drawn if they are chroma keyed |
LV_MEM_CUSTOM |
0 |
1: use custom malloc/free, 0: use the built-in lv_mem_alloc() and lv_mem_free() |
LV_MEM_SIZE |
DEMO_GUI_HEAP_SIZE |
Size of the memory available for lv_mem_alloc() in bytes (>= 2kB) |
LV_MEM_ADR |
0 |
Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too. |
LV_MEMCPY_MEMSET_STD |
0 |
Use the standard memcpy and memset instead of LVGL’s own functions. (Might or might not be faster). |
LV_DISP_DEF_REFR_PERIOD |
15 |
Default display refresh period. LVG will redraw changed areas with this period time |
LV_INDEV_DEF_READ_PERIOD |
15 |
Input device read period in milliseconds |
LV_TICK_CUSTOM |
1 |
Use a custom tick source that tells the elapsed time in milliseconds. It removes the need to manually update the tick with lv_tick_inc() |
LV_TICK_CUSTOM_INCLUDE |
“gdi.h” |
Header for the system time function. |
LV_TICK_CUSTOM_SYS_TIME_EXPR |
gdi_convert_ticks_to_us(gdi_get_sys_uptime_ticks()) / 1000 |
Expression evaluating to current system time in milliseconds. |
LV_DPI_DEF |
130 |
Default Dot Per Inch. Used to initialize default sizes such as widgets sized, style paddings. |
LV_DRAW_COMPLEX |
1 |
Enable complex draw engine. Required to draw shadow, gradient, rounded corners, circles, arc, skew lines, image transformations or any masks |
LV_SHADOW_CACHE_SIZE |
0 |
Allow buffering some shadow calculation. LV_SHADOW_CACHE_SIZE is the max. shadow size to buffer, where shadow size is shadow_width + radius. Caching has LV_SHADOW_CACHE_SIZE^2 RAM cost. |
LV_IMG_CACHE_DEF_SIZE |
0 |
Default image cache size. Image caching keeps the images opened. If only the built-in image formats are used there is no real advantage of caching. With complex image decoders (e.g. PNG or JPG) caching can save the continuous open/decode of images. However, the opened images might consume additional RAM. 0: to disable caching |
LV_DISP_ROT_MAX_BUF |
10*1024 |
Maximum buffer size to allocate for rotation. Only used if software rotation is enabled in the display driver. |
LV_USE_EXTERNAL_RENDERER |
1 |
Use the external renderer. Replaces some of the default rendering functions. |
DLG_LVGL_USE_GPU_DA1470X |
1 |
Use Dialog’s D/AVE 2D GPU for DA1470x platforms. |
DLG_LVGL_GPU_DA1470X_INCLUDE_PATH |
“dave_driver.h” |
Define the D/AVE 2D driver file. |
DLG_LVGL_GPU_BLIT_MASK_BUFFER_SIZE |
(20 * 1024) |
Maximum size of temporary buffer used by the GPU to perform BLIT operations with mask. The size of the buffer affects the number of blocks required for a BLIT operation and hence the performance of the operation. A minimum value of 20K is recommended. |
DLG_LVGL_GPU_BLIT_MASK_SIZE_LIMIT |
2000 |
Set the low limit in pixels that a BLIT operation with mask is performed by the GPU. SW is faster in smaller areas whereas the GPU is faster in larger areas. Recommended value of 2000 |
LV_USE_LOG |
0 |
Disable/Enable the log module. Enabling logging will affect, depending on the log level, the system performance. |
LV_USE_ASSERT_NULL |
1 |
Check if the parameter is NULL. (Very fast, recommended) |
LV_USE_ASSERT_MALLOC |
1 |
Checks is the memory is successfully allocated or no. (Very fast, recommended) |
LV_USE_ASSERT_STYLE |
1 |
Check if the styles are properly initialized. (Very fast, recommended) |
LV_USE_ASSERT_MEM_INTEGRITY |
0 |
Check the integrity of lv_mem after critical operations. (Slow) |
LV_USE_ASSERT_OBJ |
0 |
Check the object’s type and existence (e.g. not deleted). (Slow) |
LV_ASSERT_HANDLER_INCLUDE |
“osal.h” |
Add a custom handler when assert happens e.g. to restart the MCU |
LV_ASSERT_HANDLER |
OS_ASSERT(0); |
Halt by default |
LV_USE_PERF_MONITOR |
0 |
1: Show CPU usage and FPS count in the right bottom corner |
LV_USE_MEM_MONITOR |
0 |
1: Show the used memory and the memory fragmentation in the left bottom corner. Requires LV_MEM_CUSTOM = 0 |
LV_USE_REFR_DEBUG |
0 |
1: Draw random colored rectangles over the redrawn areas |
LV_SPRINTF_CUSTOM |
0 |
Change the built in (v)snprintf functions |
LV_SPRINTF_USE_FLOAT |
0 |
Support for the floating-point type (%f) |
LV_USE_USER_DATA |
1 |
Pass user data to structs, functions, events, callbacks etc.… |
LV_ENABLE_GC |
0 |
Garbage Collector settings. Used if lvgl is binded to higher level language and the memory is managed by that language |
Even more macros can be found at the end of the lv_conf.h file, which are not described in the above table, related to font, text and compiler settings. The user can also enable/disable the use of the supported widgets, themes and layouts.
10.2. Library Extension
The limitation of the LVGL graphics library, in terms of the color modes, is that it doesn’t support color conversion, which means that the resource images should comply with the FBs color depth, and it doesn’t support all the color formats of the GPU. To overcome this limitation, an extension is added to the LVGL library to support color conversion, with GPU acceleration, to the most commonly used color formats by enabling the DLG_LVGL_CF definition. For instance, and as illustrated in Figure 13, a static image of ARGB8888 color depth, stored in the Flash memory, can be converted by the LVGL extension and displayed to a FB of RGB565 color mode.

Figure 13 LVGL Color Conversion Scheme
The build-in image color formats are:
LV_IMG_CF_TRUE_COLOR: Simply stores the RGB colors (in whatever color depth LVGL is configured for).
LV_IMG_CF_TRUE_COLOR_ALPHA: Like LV_IMG_CF_TRUE_COLOR but it also adds an alpha (transparency) byte for every pixel.
LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED: Like LV_IMG_CF_TRUE_COLOR but if a pixel has the LV_COLOR_TRANSP color (set in lv_conf.h) it will be transparent.
LV_IMG_CF_INDEXED_1/2/4/8BIT: Uses a palette with 2, 4, 16 or 256 colors and stores each pixel in 1, 2, 4 or 8 bits.
LV_IMG_CF_ALPHA_1/2/4/8BIT: Only stores the Alpha value with 1, 2, 4 or 8 bits. The pixels take the color of style.img_recolor and the set opacity. The source image has to be an alpha channel. This is ideal for bitmaps similar to fonts where the whole image is one color that can be altered.
LV_IMG_CF_RAW: Indicates a basic raw image (e.g. a PNG or JPG image).
LV_IMG_CF_RAW_ALPHA: Indicates that an image has alpha and an alpha byte is added for every pixel.
LV_IMG_CF_RAW_CHROMA_KEYED: Indicates that an image is chroma-keyed as described in LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED above.
The extended image color formats are:
LV_IMG_CF_AI44: Stores the alpha value with 4 bits and uses a palette with 16 colors and stores each pixel in 4 bits.
LV_IMG_CF_ARGB8888: Indicates that the image has 32 bits per pixel. 8 bits for alpha, 8 bits for red, 8 bits for green and 8 bits for blue.
LV_IMG_CF_ARGB4444: Indicates that the image has 16 bits per pixel. 4 bits for alpha, 4 bits for red, 4 bits for green, 4 bits for blue.
LV_IMG_CF_ARGB1555: Indicates that the image has 16 bit per pixel. 1 bit for alpha, 5 bits for red, 5 bits for green, 5 bits for blue.
LV_IMG_CF_RGBA8888: Indicates that the image has 32 bits per pixel: 8 bits for red, 8 bits for green, 8 bits for blue, 8 bits for alpha.
LV_IMG_CF_RGBA4444: Indicates that the image has 16 bits per pixel: 4 bits for red, 4 bits for green, 4 bits for blue, 4 bits for alpha.
LV_IMG_CF_RGBA5551: Indicates that the image has 16 bit per pixel. 5 bits for red, 5 bits for green, 5 bits for blue, 1 bit for alpha.
LV_IMG_CF_RGB888: Indicates that the image has 32 bits per pixel: 8 bits for red, 8 bits for green, 8 bits for blue, 8 bits for unused.
LV_IMG_CF_RGB565: Indicates that the image has 16 bit per pixel: 5 bits for red, 6 bits for green, 5 bits for blue.
LV_IMG_CF_RLE_FLAG: use Real Length Encoding.
The library extension requires an internal versioning of the LVGL library, so LVGL_CONF_VERSION_… macros have been added to track the changes.
Functions |
Description |
---|---|
set_px_cb_argb8888 |
Sets ARGB8888 color to a pixel in a buffer according to the special requirements of the display. |
set_px_cb_argb4444 |
Sets ARGB4444 color to a pixel in a buffer according to the special requirements of the display. |
set_px_cb_argb1555 |
Sets ARGB1555 color to a pixel in a buffer according to the special requirements of the display. |
set_px_cb_rgba8888 |
Sets RGBA8888 color to a pixel in a buffer according to the special requirements of the display. |
set_px_cb_rgba4444 |
Sets RGBA4444 color to a pixel in a buffer according to the special requirements of the display. |
set_px_cb_rgba5551 |
Sets RGBA5551 color to a pixel in a buffer according to the special requirements of the display. |
set_px_cb_rgb888 |
Sets RGB888 color to a pixel in a buffer according to the special requirements of the display. |
set_px_cb_rgb565 |
Sets RGB565 color to a pixel in a buffer according to the special requirements of the display. |
Functions |
Description |
---|---|
lv_img_buf_set_px_alpha |
Set the alpha value of a pixel of an image. The color won’t be affected. |
lv_img_buf_set_px_color |
Set the color of a pixel of an image. The alpha channel won’t be affected. |
lv_img_decoder_built_in_info |
Get info about a built-in image. |
lv_img_decoder_built_in_open |
Open a built in image. |
lv_canvas_set_buffer |
Set a buffer for the canvas. |
lv_canvas_draw_rect |
Draw a rectangle on the canvas. |
This extension reveals the necessity of internal versioning of the LVGL library, in order to track the out changes. For this purpose, the LVGL_CONF_VERSION_… macros have been added.
Macro Name |
Default Value |
Description |
---|---|---|
LVGL_CONF_VERSION_MAJOR |
8 |
Major versions for incompatible API changes. |
LVGL_CONF_VERSION_MINOR |
1 |
Minor version for new but backward-compatible functionalities |
LVGL_CONF_VERSION_PATCH |
0 |
Patch version for backward-compatible bug fixes. |
LVGL_CONF_VERSION_INFO |
dev |
Version info for distinguishing release versions from development. |
LVGL_CONF_VERSION_EXT |
5 |
Version extension for identifying the Dialog extension version |
10.3. GPU Integration
The draw pipeline of the LVGL has been structured in a way that can support SW rendering, and a mixture of SW and GPU HW rendering (LV_USE_EXTERNAL_RENDERER). The pipeline can be replaced or extended according to the system’s capabilities and the application’s requirements. As shown at Figure 14, the library consists of the core, the widgets and the extra/widgets folders containing high level functions of the graphic library, facilitating the development of the UI. The draw folder contains, among others, the lv_draw_arc, lv_draw_triangle, lv_draw_line files, which perform a part of the SW rendering process. The functions that are included in the LV_USE_EXTERNAL_RENDERER participate also in the rendering process, but they can also be accelerated by the GPU. The functions highlighted in yellow boxes, have already integrated the usage of the GPU (Table 12). More parts of the LVGL, some of those highlighted at Figure 14, can make use of the GPU, but it depends on the application’s needs, which parts it would be useful to change and become GPU accelerated, to boost the final performance.

Figure 14 LVGL Structure
The LVGL has built-in support to several GPUs (see lv_conf.h). In order to take advantage of the HW acceleration, two hook functions are provided, the gpu_fill_cb and the gpu_wait_cb. In addition to the existing callbacks, and in order to exploit the powerful features of the D/AVE 2D GPU, three new callbacks are added for the configuration of the BLIT process, the gpu_blit_with_mask_cb, the gpu_config_blit_cb and the gpu_blit_cb. All the above callbacks, which are described at Table 11, are guarded with the DLG_LVGL_USE_GPU_DA1470X definition and should be defined at the initialization structure of the display driver (static lv_disp_drv_t disp_drv;).
/*-----------------------------------
* Register the display in LVGL
*----------------------------------*/
static lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
#if LV_PORT_DISP_GPU_EN
/* Initialize GPU module */
lv_port_gpu_init();
/* Fill a memory array with a color with GPU */
disp_drv.gpu_fill_cb = lv_port_gpu_fill;
disp_drv.gpu_blit_cb = lv_port_gpu_blit;
disp_drv.gpu_blit_with_mask_cb = lv_port_gpu_blit_with_mask;
disp_drv.gpu_config_blit_cb = lv_port_gpu_config_blit;
disp_drv.gpu_wait_cb = lv_port_gpu_wait;
#endif /* LV_PORT_DISP_GPU_EN */
Function |
Description |
---|---|
gpu_fill_cb |
Fill an area in the memory with a color. API change: set the alpha value in the fill process. |
gpu_wait_cb |
Called to wait while the GPU is working. If any GPU function returns while the GPU is still working, LVGL will use this function when required to make sure GPU rendering is ready. |
gpu_blit_with_mask_cb |
Configure BLIT operation containing a mask. Masks are used in letters, lines, rectangles etc. to generate rounded or clipped corners, to mask out parts of a rectangle, etc. Masks are applied in 3 steps, BLIT the image in a temporary buffer, mix the alpha value in the temporary buffer with the mask and finally BLIT the temporary buffer as image. New GPU callback. |
gpu_config_blit_cb |
Configure the flags for the BLIT operation. New GPU callback. |
gpu_blit_cb |
BLIT an image. New GPU callback. |
Function |
Description |
---|---|
map_normal() |
Copy an image to an area. If the color format is supported by the GPU, configure and use the GPU BLIT operation. API change: add the image color format. |
_lv_blend_map() |
Copy a map (image) to a display buffer. API change: add the image color format. |
fill_normal() |
Fill an area with a color. Configure the BLIT operation and perform the BLIT using the GPU, if a masked area exists. |
lv_draw_map() |
Draw a color map to the display (image). API change: add the image color format. |